package cz.muni.fi.pa165.hauntedhouses.service;

import cz.muni.fi.pa165.hauntedhouses.dao.GhostDAO;
import cz.muni.fi.pa165.hauntedhouses.dto.AbilityType;
import cz.muni.fi.pa165.hauntedhouses.dto.GhostDTO;
import cz.muni.fi.pa165.hauntedhouses.dto.HouseDTO;
import cz.muni.fi.pa165.hauntedhouses.entity.Ghost;
import cz.muni.fi.pa165.hauntedhouses.util.DTOAndDAOMapper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *A service layer class for ghost ensuring
 * transactional behavior for all methods.
 * @author Jan Vyhnánek
 */
@Service
@Transactional
public class GhostServiceImpl implements GhostService {
    
    @Autowired
    private GhostDAO ghostDAO;

    public void setGhostDAO(GhostDAO ghostDAO) {
        this.ghostDAO = ghostDAO;
    }
    
    @Override
    public void create(GhostDTO ghost) {
        Ghost gh = DTOAndDAOMapper.DTOGhostToEntityGhost(ghost);
        ghostDAO.create(gh);
        ghost.setId(gh.getId());
        
        for(int i = 0; i < ghost.getAbilities().size(); i++){
            ghost.getAbilities().get(i).setId(gh.getAbilities().get(i).getId());
        }
        if(ghost.getHome() != null){
            ghost.getHome().setId(gh.getHome().getId());
        }
    }

    @Override
    public void update(GhostDTO ghost) {     
        Ghost gh = DTOAndDAOMapper.DTOGhostToEntityGhost(ghost);
        ghostDAO.update(gh);
        ghost = DTOAndDAOMapper.GhostEntityToDTOGhost(gh);
    }

    @Override
    public void remove(GhostDTO ghost) {        
        ghostDAO.remove(DTOAndDAOMapper.DTOGhostToEntityGhost(ghost));
    }

    @Override
    public GhostDTO get(Long id) {
        return (DTOAndDAOMapper.GhostEntityToDTOGhost(ghostDAO.get(id)));
    }

    @Override
    public List<GhostDTO> findAll() {        
        List <GhostDTO> dtoList = new ArrayList<>();
        for (Ghost ghost : ghostDAO.findAll()) {
            dtoList.add(DTOAndDAOMapper.GhostEntityToDTOGhost(ghost));
        }
        return Collections.unmodifiableList(dtoList);
    }

    @Override
    public List<GhostDTO> findByName(String name) {        
        List <GhostDTO> dtoList = new ArrayList<>();
        for (Ghost ghost : ghostDAO.findByName(name)) {
            dtoList.add(DTOAndDAOMapper.GhostEntityToDTOGhost(ghost));
        }
        return Collections.unmodifiableList(dtoList);
    }

    @Override
    public List<GhostDTO> findByHouse(HouseDTO house) {        
        List <GhostDTO> dtoList = new ArrayList<>();
        for (Ghost ghost : ghostDAO.findByHouse(DTOAndDAOMapper.DTOHouseToEntityHouse(house))) {
            dtoList.add(DTOAndDAOMapper.GhostEntityToDTOGhost(ghost));
        }
        return Collections.unmodifiableList(dtoList);
    }

    @Override
    public List<GhostDTO> findByLevel(Integer level) {        
        List <GhostDTO> dtoList = new ArrayList<>();
        for (Ghost ghost : ghostDAO.findByLevel(level)) {
            dtoList.add(DTOAndDAOMapper.GhostEntityToDTOGhost(ghost));
        }
        return Collections.unmodifiableList(dtoList);
    }

    @Override
    public List<GhostDTO> findByType(AbilityType type) {        
        List <GhostDTO> dtoList = new ArrayList<>();
        for (Ghost ghost : ghostDAO.findByType(type)) {
            dtoList.add(DTOAndDAOMapper.GhostEntityToDTOGhost(ghost));
        }
        return Collections.unmodifiableList(dtoList);
    }
}
